package com.yntx.usercenter.authorization.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yntx.usercenter.authorization.converter.RoleConverter;
import com.yntx.usercenter.authorization.dto.*;
import com.yntx.usercenter.authorization.mapper.RoleMapper;
import com.yntx.usercenter.authorization.mapper.RolePermissionMapper;
import com.yntx.usercenter.authorization.mapper.UserRoleMapper;
import com.yntx.usercenter.authorization.po.Role;
import com.yntx.usercenter.authorization.po.RolePermission;
import com.yntx.usercenter.authorization.po.UserRole;
import com.yntx.usercenter.authorization.service.RoleService;
import com.yntx.usercenter.authorization.vo.RoleVO;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色服务impl
 *
 * @author wuzhengyu
 * @date 2023/05/08 16:53
 */
@Service
@AllArgsConstructor
public class RoleServiceImpl implements RoleService {

    private RoleMapper roleMapper;

    private UserRoleMapper userRoleMapper;

    private RolePermissionMapper rolePermissionMapper;

    private static final RoleConverter CONVERTER = RoleConverter.INSTANCE;

    @Override
    public List<RoleVO> listByUser(Long userId) {
        LambdaQueryWrapper<UserRole> userRoleQuery = new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId);
        List<UserRole> userRoleList = userRoleMapper.selectList(userRoleQuery);
        if (CollectionUtils.isEmpty(userRoleList)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Role> roleQuery = new LambdaQueryWrapper<Role>().in(Role::getId, userRoleList.stream().map(UserRole::getId).collect(Collectors.toSet()));
        List<Role> roleList = roleMapper.selectList(roleQuery);
        return CONVERTER.role2RoleVOList(roleList);
    }

    @Override
    public List<RoleVO> list(RoleDTO roleDTO) {
        LambdaQueryWrapper<Role> roleQuery = new LambdaQueryWrapper<Role>()
                .eq(StringUtils.isNotEmpty(roleDTO.getParentCode()), Role::getParentCode, roleDTO.getParentCode())
                .eq(StringUtils.isNotEmpty(roleDTO.getCode()), Role::getCode, roleDTO.getCode())
                .like(StringUtils.isNotEmpty(roleDTO.getName()), Role::getName, roleDTO.getName());
        List<Role> roleList = roleMapper.selectList(roleQuery);
        return CONVERTER.role2RoleVOList(roleList);
    }

    @Override
    public Long add(RoleDTO dto) {
        Role role = CONVERTER.roleAddDTO2Role(dto);
        roleMapper.insert(role);
        return role.getId();
    }

    @Override
    public boolean delete(RoleDeleteDTO dto) {
        LambdaQueryWrapper<Role> roleQuery = new LambdaQueryWrapper<Role>()
                .in(CollectionUtils.isNotEmpty(dto.getIds()), Role::getId, dto.getIds())
                .in(CollectionUtils.isNotEmpty(dto.getCodes()), Role::getCode, dto.getCodes());
        int delete = roleMapper.delete(roleQuery);
        return true;
    }

    @Override
    public boolean update(RoleUpdateDTO dto) {
        Role role = CONVERTER.roleUpdateDTO2Role(dto);
        int update = roleMapper.updateById(role);
        return update > 0;
    }

    // todo: 改为批量
    @Override
    public boolean assignRole(AssignRoleDTO dto) {
        List<Long> userIds = dto.getUserIds();
        List<Long> roleIds = dto.getRoleIds();
        if (CollectionUtils.isEmpty(userIds) || CollectionUtils.isEmpty(roleIds)) {
            throw new IllegalArgumentException("用户ID和角色ID不能为空");
        }
        for (Long userId : userIds) {
            for (Long roleId : roleIds) {
                LambdaQueryWrapper<UserRole> userRoleQuery = new LambdaQueryWrapper<UserRole>()
                        .eq(UserRole::getUserId, userId)
                        .eq(UserRole::getRoleId, roleId);
                boolean exists = userRoleMapper.exists(userRoleQuery);
                if (!exists) {
                    UserRole userRole = UserRole.builder().userId(userId).roleId(roleId).build();
                    userRoleMapper.insert(userRole);
                }
            }
        }
        return true;
    }

    @Override
    public boolean unAssignRole(AssignRoleDTO dto) {
        List<Long> userIds = dto.getUserIds();
        List<Long> roleIds = dto.getRoleIds();
        if (CollectionUtils.isEmpty(userIds) || CollectionUtils.isEmpty(roleIds)) {
            throw new IllegalArgumentException("用户ID和角色ID不能为空");
        }
        for (Long userId : userIds) {
            for (Long roleId : roleIds) {
                LambdaQueryWrapper<UserRole> userRoleQuery = new LambdaQueryWrapper<UserRole>()
                        .eq(UserRole::getUserId, userId)
                        .eq(UserRole::getRoleId, roleId);
                userRoleMapper.delete(userRoleQuery);
            }
        }
        return true;
    }

    @Override
    public boolean assignPermission(AssignPermissionDTO dto) {
        List<Long> permissionIds = dto.getPermissionIds();
        List<Long> roleIds = dto.getRoleIds();
        if (CollectionUtils.isEmpty(permissionIds) || CollectionUtils.isEmpty(roleIds)) {
            throw new IllegalArgumentException("权限ID和角色ID不能为空");
        }
        for (Long permissionId : permissionIds) {
            for (Long roleId : roleIds) {
                LambdaQueryWrapper<RolePermission> userRoleQuery = new LambdaQueryWrapper<RolePermission>()
                        .eq(RolePermission::getPermissionId, permissionId)
                        .eq(RolePermission::getRoleId, roleId);
                boolean exists = rolePermissionMapper.exists(userRoleQuery);
                if (!exists) {
                    RolePermission userRole = RolePermission.builder().permissionId(permissionId).roleId(roleId).build();
                    rolePermissionMapper.insert(userRole);
                }
            }
        }
        return true;
    }

    @Override
    public boolean unAssignPermission(AssignPermissionDTO dto) {
        List<Long> permissionIds = dto.getPermissionIds();
        List<Long> roleIds = dto.getRoleIds();
        if (CollectionUtils.isEmpty(permissionIds) || CollectionUtils.isEmpty(roleIds)) {
            throw new IllegalArgumentException("权限ID和角色ID不能为空");
        }
        for (Long permissionId : permissionIds) {
            for (Long roleId : roleIds) {
                LambdaQueryWrapper<RolePermission> userRoleQuery = new LambdaQueryWrapper<RolePermission>()
                        .eq(RolePermission::getPermissionId, permissionId)
                        .eq(RolePermission::getRoleId, roleId);
                rolePermissionMapper.delete(userRoleQuery);
            }
        }
        return true;
    }

}
